package com.gw2.gw2world;

import java.net.URI;

import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.json.JSONObject;

import com.gw2.gw2world.controller.DatabaseOpenHelper;
import com.gw2.gw2world.controller.ServerManager;
import com.gw2.gw2world.controller.Tools;

import android.os.AsyncTask;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ProgressBar;
import android.widget.RadioButton;
import android.widget.RadioGroup;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;

/** Check version, download game data (server/map/event names).
 * If it is the first run, the user have to select language and servers.
 */
public class InstallActivity extends Activity implements OnClickListener, android.content.DialogInterface.OnClickListener {
	DatabaseOpenHelper dbHelper;
	private static final String TAG="InstallActivity";
	private SharedPreferences prefs;
	private SharedPreferences.Editor editor;
	private ProgressBar pb;
	private TextView tv;
	private RadioGroup rg;
	private Button b_ok_language;
	private RelativeLayout rl_server;
	private Intent intent_home;
	private AsyncInstall installer;
	private ServerManager serverManager;
	private AlertDialog dialog;
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		dbHelper = new DatabaseOpenHelper(InstallActivity.this, "database", null, 1);
		Tools.forceLocale(this);
		Tools.enableWifi(this);
		setContentView(R.layout.install);
		installer=new AsyncInstall();
		prefs=PreferenceManager.getDefaultSharedPreferences(this);
		pb=(ProgressBar)findViewById(R.id.pb_install);
		tv=(TextView)findViewById(R.id.tv_pbstatus);
		rg=(RadioGroup)findViewById(R.id.rg_language);
		b_ok_language=(Button)findViewById(R.id.b_ok_language);
		b_ok_language.setOnClickListener(this);
		rl_server=(RelativeLayout)findViewById(R.id.rl_install);
		dialog=new AlertDialog.Builder(this)
			.setPositiveButton(android.R.string.yes, this)
			.setNegativeButton(android.R.string.no, this)
			.setMessage(R.string.wifi_disabled).create();
		if(!Tools.isWifiEnabled(this)) dialog.show();
		else checkLanguageOrStart();
		
	}
	private void checkLanguageOrStart() {
		if(prefs.getString("language", "").equals("")) {
			tv.setText(R.string.waiting_user_selection);
			rg.setVisibility(View.VISIBLE);
		} else installer.execute();
	}
	@Override
	public void onClick(View v) {
		//check if language is selected and start downloading if OK
		if(v.getId()==R.id.b_ok_language) {
			if(rg.getCheckedRadioButtonId()==-1) {
				Toast.makeText(this, R.string.msg_select_language, Toast.LENGTH_SHORT).show();
				return;
			}
			rg.setVisibility(View.GONE);
			editor=prefs.edit();
			RadioButton rb=(RadioButton)findViewById(rg.getCheckedRadioButtonId());
			if(rb.getId()==R.id.rb_english) editor.putString("language", "en");
			else if(rb.getId()==R.id.rb_french) editor.putString("language", "fr");
			else if(rb.getId()==R.id.rb_german) editor.putString("language", "de");
			else if(rb.getId()==R.id.rb_spanish) editor.putString("language", "es");
			editor.putInt("build", 0);
			editor.commit();
			Tools.forceLocale(this);
			installer.execute();
		} else if(v.getId()==serverManager.getOkButtonId()) {
			serverManager.writePreferences();
			if(!serverManager.isHomeSelected()) {
				Toast.makeText(this, R.string.msg_select_server, Toast.LENGTH_SHORT).show();
				return;
			}
			rl_server.getChildAt(3).setVisibility(View.GONE);
			if(installer.isRunning()) return;
			intent_home=new Intent(InstallActivity.this, HomeActivity.class);
			startActivity(intent_home);
			super.finish();
		}
	}
	
	/** Install database if first run, check game version for updates. Download server names,
	 * map names and event names if the version is different from preferences.
	 */
	private class AsyncInstall extends AsyncTask<Short, Short, Boolean> {
		//TODO: handle screen rotation
		// http://www.fattybeagle.com/2011/02/14/android-asynctasks-during-a-screen-rotation-part-i/
		// http://www.fattybeagle.com/2011/02/15/android-asynctasks-during-a-screen-rotation-part-ii/
		private static final short VERSION=1;
		private static final short UPDATE=2;
		private static final short SERVER=3;
		private static final short PROGRESSION=4; //to update progress bar
		private static final short ERROR=-1;
		private int progress;
		private boolean running=true;
		/**
		 * Download a page
		 * @param url Page URL
		 * @return Source code
		 */
		private String download(String url) {
			android.util.Log.d(TAG, "Downloading "+url);
			HttpClient client = new DefaultHttpClient();
			try {
				HttpGet request = new HttpGet(new URI(url));
				request.addHeader("accept", "application/json");
				HttpResponse response = client.execute(request);
				return Tools.convertStreamToString(response.getEntity().getContent());
			}
			catch (Exception e) {
				e.printStackTrace();
				return null;
			}
		}
		
		@Override
		protected void onPreExecute() {
			Tools.lockScreen(InstallActivity.this);
			super.onPreExecute();
		}
		@Override
		protected Boolean doInBackground(Short... values) {
			progress=0;
			//checking version
			publishProgress(VERSION);
			String json=download("https://api.guildwars2.com/v1/build.json");
			if(json==null) {
				publishProgress(ERROR);
				return false;
			}
			try {
				int id = new JSONObject(json).getInt("build_id");
				//dbHelper.installLivingWorldEvents();
				//dbHelper.insertWorldEvents();
				//android.util.Log.d(TAG, "build: "+String.valueOf(id));
				//android.util.Log.d(TAG, "build: "+String.valueOf(prefs.getInt("build", 0)));
				if(id!=prefs.getInt("build", 0)) {
					publishProgress(UPDATE);
					//downloading servers, map names and event names
					String lang=prefs.getString("language", "");
					//download and update server names
					dbHelper.installServers(download("https://api.guildwars2.com/v1/world_names.json?lang="+lang),lang);
					progress++; publishProgress(SERVER);
					dbHelper.installMaps(download("https://api.guildwars2.com/v1/map_names.json?lang="+lang),lang);
					progress++; publishProgress(PROGRESSION);
					dbHelper.installMapDetails(download("https://api.guildwars2.com/v1/maps.json"));
					progress++; publishProgress(PROGRESSION);
					dbHelper.installEvents(download("https://api.guildwars2.com/v1/event_names.json?lang="+lang),lang);
					progress++; publishProgress(PROGRESSION);
					dbHelper.installEventDetails(download("https://api.guildwars2.com/v1/event_details.json"));
					progress++; publishProgress(PROGRESSION);
					android.content.SharedPreferences.Editor editor=prefs.edit();
					editor.putInt("build", id);
					editor.putString("bugged_events", "");
					editor.commit();
					dbHelper.insertWorldEvents();
					dbHelper.installLivingWorldEvents();
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
			return true;
		}

		@Override
		protected void onPostExecute(Boolean result) {
			tv.setText(R.string.init_done);
			pb.setProgress(5); //5 files to download
			Tools.unlockScreen(InstallActivity.this);
			if(prefs.getInt("home_server", 0)!=0) {
				intent_home=new Intent(InstallActivity.this, HomeActivity.class);
				startActivity(intent_home);
				InstallActivity.super.finish();
			}
			running=false;
			super.onPostExecute(result);
		}
		public boolean isRunning() {return running;}
		@Override
		protected void onProgressUpdate(Short... values) {
			switch (values[0]) {
			case VERSION:
				tv.setText(R.string.checking_version);
				break;
			case SERVER:
				tv.setText(R.string.downloading);
				updateProgression();
				if(prefs.getInt("home_server", 0)==0) {
					serverManager=new ServerManager(InstallActivity.this);
					serverManager.setMode(ServerManager.MODE_USERCOMMIT);
					View v=serverManager.getView();
					serverManager.setOnOkClickListener(InstallActivity.this);
					v.setBackgroundResource(R.drawable.rounded_rectangle);
					RelativeLayout.LayoutParams params=new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
					params.addRule(RelativeLayout.BELOW, pb.getId());
					rl_server.addView(v, 3, params);
				}
				break;
			case UPDATE:
				tv.setText(R.string.downloading);
				break;
			case PROGRESSION:
				updateProgression();
				break;
			case ERROR:
				Toast.makeText(InstallActivity.this, R.string.unable_to_download, Toast.LENGTH_LONG).show();
				cancel(true);
				finish();
				break;
			default:
				break;
			}
			super.onProgressUpdate(values);
		}
		private void updateProgression() {
			pb.setIndeterminate(false);
			pb.setMax(5);
			pb.setProgress(progress);
		}
	}

	@Override
	public void onClick(DialogInterface di, int which) {
		if(which==AlertDialog.BUTTON_POSITIVE) Tools.enableWifi(this);
		checkLanguageOrStart();
	}
}
